package redis

import (
	"context"
	"fmt"
	"log"
	"regexp"
	"sort"
	"strconv"
	"sync"

	. "github.com/redis/go-redis/v9"
	redisCluster "github.com/redis/go-redis/v9"
)

// 初始化集群连接
func initClientCluster(addr string) (rdbCluster *redisCluster.ClusterClient, err error) {
	rdbCluster = redisCluster.NewClusterClient(&redisCluster.ClusterOptions{
		Addrs:    []string{addr},
		Password: Password(),
	})
	_, err = rdbCluster.Ping(context.Background()).Result()
	if err != nil {
		log.Println("initClientCluster err: ", err)
		return nil, err
	}
	return rdbCluster, nil
}

// 根据集群clientlist的killnormal
func KillNormalCluster(addr string) string {
	var result string
	var ctx = context.Background()
	rdb, err := initClientCluster(addr)
	if err != nil {
		return "连接不上redis cluster: " + err.Error()
	}
	defer rdb.Close()

	cls := New(rdb)

	err = cls.ClientKill(ctx)
	if err != nil {
		return err.Error()
	}
	result = "集群killnormal成功"
	return result
}

// 根据集群clientlist的groupBy
func GroupByClientCluster(addr string) string {
	var result string
	var resultMap = make(map[string]int)
	var ctx = context.Background()

	type redisR struct {
		addr string
		num  int
	}
	var redisList = make([]*redisR, 0)

	rdb, err := initClientCluster(addr)
	if err != nil {
		return "连接不上redis"
	}
	defer rdb.Close()

	//cluse := Cluster{Cls:rdb} 有导出字段, 无法复制
	cls := New(rdb) //这里也不行..

	listClient := cls.ClientList(ctx).Value

	rex := regexp.MustCompile("id=.*addr=(.*?):.*\n")
	subMatchs := rex.FindAllStringSubmatch(listClient, -1) //匹配括号里的
	for _, v := range subMatchs {
		if _, ok := resultMap[v[1:][0]]; !ok {
			resultMap[v[1:][0]] = 0
		}
		resultMap[v[1:][0]]++
	}

	for k, v := range resultMap {
		a := &redisR{addr: k, num: v}
		redisList = append(redisList, a)
	}

	sort.SliceStable(redisList, func(i int, j int) bool {
		return redisList[i].num > redisList[j].num
	})

	// 已经按照索引排序
	for _, val := range redisList {
		res := val.addr + " :: " + strconv.Itoa(val.num)
		result += res + "\n"
	}
	return result
}

// scan集群，并del数据
func DelScanCluster(addr string, delPattern string, wait int) string {
	var result string
	var ctx = context.Background()

	type Val struct {
		Value int64
		sync.Mutex
	}

	rdb, err := initClientCluster(addr)
	if err != nil {
		return "连接不上redis cluster: " + err.Error()
	}
	defer rdb.Close()

	c := New(rdb)
	tmp := &Val{Value: 0}

	err = c.Cls.ForEachMaster(ctx, func(ctx context.Context, master *Client) error {
		var err error

		//_, err = client.ClientKillByFilter(ctx, "type", "normal").Result()
		//
		for {
			var keys []string
			var err error
			var cursor uint64
			//*扫描所有key，每次500条
			keys, cursor, err = master.Scan(ctx, cursor, delPattern, 500).Result()

			if err != nil {
				panic(err)
			}
			n := len(keys)
			fmt.Println("key ")
			fmt.Println(keys)
			tmp.Value += int64(n)
			for _, key := range keys {
				err = master.Del(context.Background(), key).Err()
				fmt.Printf("%v delele\n", key)
			}
			// 删除集群的会删不掉

			//rdb.Del(ctx, keys...).Result()
			WaitSleep(wait)
			if cursor == 0 {
				break
			}
		}

		return err
	})

	result = fmt.Sprintf("%d keys del .", tmp.Value)
	return result
}
